Imports KanBan.Pgd.Domain.ValueObjects
Imports KanBan.Pgd.Presentation.Session

Namespace Helpers

    Public Class UIContextualizationHelper

        Private Const PublicControlTag As String = "public"

        Public Shared Sub ContextualizeMenuOptions(ByVal items As ToolStripItemCollection)

            For Each item As ToolStripMenuItem In items

                If Not IsTagNullOrPublic(item.Tag) Then

                    item.Visible = IsElementVisible(item.Tag)

                Else
                    item.Visible = True
                End If

                If item.DropDownItems.Count > 0 Then
                    ContextualizeMenuOptions(item.DropDownItems)
                End If
            Next

            SetVisibilityTree(items)

        End Sub

        Private Shared Function GetTagArray(ByVal tag As Object) As String()

            Return tag.ToString().Trim().ToLower().Split(CChar(";"))

        End Function

        Public Shared Sub SetVisibilityTree(ByVal items As ToolStripItemCollection)

            For Each item As ToolStripMenuItem In items
                If item.DropDownItems.Count > 0 Then
                    Dim parentIsVisible As Boolean = AtLeastOneItemIsVisible(item.DropDownItems)
                    item.Visible = parentIsVisible

                    If parentIsVisible Then
                        SetVisibilityTree(item.DropDownItems)
                    End If

                End If
            Next

        End Sub

        Private Shared Function AtLeastOneItemIsVisible(ByVal items As ToolStripItemCollection) As Boolean

            Dim visible As Boolean = False

            For Each item As ToolStripMenuItem In items
                If IsElementVisible(item.Tag) Then
                    visible = True
                    Exit For
                End If
            Next

            Return visible

        End Function

        <Obsolete()> _
        Public Shared Sub ContextualizeControls(ByVal controls As Control.ControlCollection)

            For Each c As Control In controls

                If Not IsTagNullOrPublic(c.Tag) Then

                    'ToDo: Consider extending this functionality!
                    c.Visible = IsElementVisible(c.Tag)

                Else
                    If c.HasChildren Then
                        ContextualizeControls(c.Controls)
                    End If
                End If

            Next

        End Sub

        Private Shared Function IsElementVisible(ByVal elementTag As Object) As Boolean

            If IsTagNullOrPublic(elementTag) Then Return True

            Dim itemVisible As Boolean = True

            Dim tagArray As String() = GetTagArray(elementTag)

            For i As Integer = 0 To tagArray.Length - 1
                Dim userHasPermission As Boolean = False
                'Todo: refactorize using HasPermission Method
                For Each p As Permission In ClientSession.UserCredentials.Permissions
                    If p.Name.ToLower() = tagArray(i) Then
                        userHasPermission = True
                        Exit For
                    End If
                Next

                If Not userHasPermission Then
                    itemVisible = False
                    Exit For
                End If
            Next
            Return itemVisible

        End Function

        Private Shared Function IsTagNullOrPublic(ByVal tag As Object) As Boolean

            If tag Is Nothing Then Return True
            If tag.ToString() = String.Empty Then Return True

            Dim tagArray As String() = GetTagArray(tag)

            Dim isPublic As Boolean = False

            For Each t As String In tagArray
                isPublic = t.Contains(PublicControlTag)
            Next

            Return isPublic

        End Function

        'ToDo: Validate this function
        Public Shared Sub HideNonPublicMenuOptions(ByVal items As ToolStripItemCollection)

            For Each item As ToolStripMenuItem In items
                If item.Tag IsNot Nothing Then
                    If item.Tag.ToString().Trim().ToLower() = PublicControlTag Then
                        item.Visible = True
                    Else
                        item.Visible = False
                    End If
                Else
                    item.Visible = False
                End If
            Next

        End Sub

        Public Shared Function IsControlVisible(ByVal c As Control) As Boolean

            If Not IsTagNullOrPublic(c.Tag) Then

                Return IsElementVisible(c.Tag)

            End If

            Return True

        End Function

    End Class

End Namespace